package dk.hewison.client.panels;

import com.google.gwt.user.client.*;
import com.google.gwt.user.client.ui.*;
import dk.hewison.client.AppEvent;
import dk.hewison.client.Log;
import dk.hewison.client.component.MyImage;
import dk.hewison.client.data.Callback;
import dk.hewison.client.data.DataController;
import dk.hewison.client.domain.Directory;
import dk.hewison.client.domain.Photo;
import dk.hewison.client.mvc.Register;

import java.util.List;

/**
 * @author John Hewison
 * @author $LastChangedBy: john.hewison $:  $ $LastChangedDate: 2009-02-15 12:47:07 +0000 (Sun, 15 Feb 2009) $:
 * @version $Revision: 364 $:
 */
public class PhotoListHolder extends Composite {
    public static final int ALBUM_SIZE = 120;

    private DeckPanel deckPanel;

    private Directory directory;
    //private Fade fadeIn;

    int imageCount;

    private double skim;
    private int coverPos = 0;
    private Timer mouseOutTimer;

    private PopupPanel imagePopup;

    //NEffectPanel effectPanel;
    //NEffectPanel effectPanel;

    public PhotoListHolder(Directory directory, LoadListener loadListener) {

        this.directory = directory;
        MyImage albumCover;
        Photo photo;
        if (directory.getCoverPhotoName() == null || directory.getCoverPhotoName().length() == 0) {
            photo = new Photo("./", "da.gif");
        } else {
            photo = new Photo(directory.getAbsolutePath(), directory.getCoverPhotoName());
        }

        directory.setCoverPhoto(photo);
        albumCover = new MyImage(photo);
        albumCover.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);

        if (loadListener != null) {
            albumCover.addLoadListener(loadListener);
        }


        mouseOutTimer = new Timer() {
            @Override
            public void run() {
                deckPanel.showWidget(coverPos);
                Image i = (Image) deckPanel.getWidget(coverPos);
                i.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
            }
        };

        /*image.addLoadListener(new LoadListener() {
            public void onError(Widget sender) {

            }

            public void onLoad(Widget sender) {
                //effectPanel.playEffects();
            }
        });*/

        //init();

        deckPanel = new DeckPanel();
        deckPanel.setAnimationEnabled(false);

        addImage(albumCover);

        VerticalPanel mainPanel = new VerticalPanel();
        mainPanel.add(deckPanel);
        Label label = new Label(directory.getFolderName());
        mainPanel.add(label);
        mainPanel.setStyleName("photolistholder");
        mainPanel.setCellHorizontalAlignment(label, VerticalPanel.ALIGN_CENTER);

        /* albumCover.addMouseListener(new MouseListenerAdapter() {
            @Override
            public void onMouseEnter(Widget sender) {
                super.onMouseEnter(sender);
                deckPanel.remove(albumCover);
            }

            @Override
            public void onMouseLeave(Widget sender) {
                super.onMouseLeave(sender);
                deckPanel.add(albumCover);
            }
        });*/


        VerticalPanel panel = new VerticalPanel();
        DecoratorPanel decoratorPanel = new DecoratorPanel();
        decoratorPanel.add(mainPanel);
        panel.add(decoratorPanel);
        //panel.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
        //decoratorPanel.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);

        initWidget(panel);

        panel.setStyleName("albumthumbnail");
        sinkEvents(Event.MOUSEEVENTS | Event.KEYEVENTS | Event.ONCLICK);

        /*deckPanel.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
        setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
        setWidth(ALBUM_SIZE + "px");*/


        DeferredCommand.addCommand(new Command() {
            public void execute() {
                deckPanel.showWidget(coverPos);
                deckPanel.getWidget(coverPos).setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
            }
        });

    }


    private void addImage(MyImage image) {
        if (deckPanel == null) return;
        deckPanel.add(image);
        //image.addClickListener(imageClickListener);
    }

    private void loadAlbumThumbnails(List<Photo> photos) {
        imageCount = photos.size();
        skim = (double) ALBUM_SIZE / (double) imageCount;

        for (Photo photo : photos) {

            MyImage image = new MyImage(photo);
            if (photo.equals(directory.getCoverPhoto())) {
                final Image newCover = image;
                Log.debug("PhotoListHolder.loadAlbumThumbnails");
                image.addLoadListener(new LoadListener() {
                    public void onError(Widget sender) {
                    }

                    public void onLoad(Widget sender) {
                        deckPanel.remove(0);
                        coverPos = deckPanel.getWidgetIndex(newCover);
                        deckPanel.showWidget(coverPos);
                        deckPanel.getWidget(coverPos).setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
                    }
                });
            }
            image.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
            addImage(image);
        }
        directory.setPhotos(photos);
    }

    @Override
    public void onBrowserEvent(Event event) {
        //super.onBrowserEvent(event);

        switch (DOM.eventGetType(event)) {
            case Event.ONMOUSEMOVE: {
                doMouseMove(event);
                break;
            }
            case Event.ONMOUSEOUT:
                mouseOutTimer.schedule(200);
                break;
            case Event.ONMOUSEOVER:
                mouseOutTimer.cancel();
                break;
            case Event.ONCLICK:
                onClick(event);
                break;

            default: {
                // Do nothing
            }
        }
    }


    private void onClick(Event event) {
        Log.debug("PhotoListHolder.onClick");

        if (event.getAltKey()) {

            MyImage image = (MyImage) deckPanel.getWidget(deckPanel.getVisibleWidget());

            // Create a popup to show the full size image
            if (imagePopup == null) {
                imagePopup = new PopupPanel(true);
                imagePopup.setAnimationEnabled(true);
            }
            MyImage myImage = new MyImage(image);
            myImage.showImage();
            myImage.addClickListener(new ClickListener() {
                public void onClick(Widget sender) {
                    imagePopup.hide();
                }
            });
            imagePopup.setWidget(myImage);
            imagePopup.setPopupPosition(getParent().getAbsoluteLeft(), getParent().getAbsoluteTop());
            imagePopup.show();
            /*myImage.addClickListener(new ClickListener() {
                public void onClick(Widget sender) {
                    imagePopup.hide();
                }
            });*/
        } else {
            openFolder();

        }

    }

    private void openFolder() {
        Register.getInstance().eventOccurred(new AppEvent<Directory>(AppEvent.Event.ALBUM_SELECTED, directory));
    }

    private void doMouseMove(Event event) {
        final Element senderElem = getElement();
        int x = DOM.eventGetClientX(event)
                - DOM.getAbsoluteLeft(senderElem)
                + DOM.getElementPropertyInt(senderElem, "scrollLeft")
                + Window.getScrollLeft();
        /*int y = DOM.eventGetClientY(event)
- DOM.getAbsoluteTop(senderElem)
+ DOM.getElementPropertyInt(senderElem, "scrollTop")
+ Window.getScrollTop();*/
        //albumCover.setVisible(false);

        if (skim == 0) return;
        int imagePos = (int) (x / skim);
        //Log.debug("" + "x:" + x + " pos:" + imagePos);
        if (imagePos == deckPanel.getVisibleWidget()) return;


        if (imagePos >= imageCount) imagePos = imageCount - 1;
        if (imagePos < 0) imagePos = 0;

        MyImage image;
        try {
            image = (MyImage) deckPanel.getWidget(imagePos);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        if (!image.isLoaded()) {
            Log.debug("image not yet loaded");
            return;
        }

        deckPanel.showWidget(imagePos);
        //deckPanel.setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
        deckPanel.getWidget(imagePos).setPixelSize(ALBUM_SIZE, ALBUM_SIZE);
    }


    /*private void init() {
        initEffect();
        effectPanel = new NEffectPanel();
        effectPanel.addEffect(fadeIn);
        effectPanel.add(image);


        //effectPanel.setEffectsLength(0.3);
    }

    public void show() {
        effectPanel.playEffects();
    }


    public void initEffect() {
        fadeIn = new MyFade();
        fadeIn.getProperties().setStartValue("0");
        fadeIn.getProperties().setEndValue("100");
    }


    class MyFade extends Fade {
        MyFade() {
            effectLengthSeconds = 0.3;
        }
    }*/

    public void loadThumbnails() {
        if (directory.isLoaded()) {
            loadAlbumThumbnails(directory.getPhotos());
        } else {
            DataController.getInstance().getDirectoryImageNames(directory, new Callback<Directory>() {

                public void doSuccess(Directory directory) {
                    loadAlbumThumbnails(directory.getPhotos());
                }
            });
        }
    }
}